package com.example.perftool2;

import android.util.Log;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

public class DumpsysCpuInfo {

    private static final String TAG = DumpsysCpuInfo.class.getSimpleName();
    public static final String COMMAND_EXIT = "exit\n";
    public static final String COMMAND_LINE_END = "\n";
    public static final String COMMAND_DUMPSYS = "dumpsys cpuinfo";

    private ArrayList<AppInfo> runningApps;
    private HashSet<Integer> mPidSet;

    public void getData(ArrayList<AppInfo> runningApps) {
        this.runningApps = runningApps;
        mPidSet = new HashSet<>();
        for(AppInfo appInfo : runningApps) {
            mPidSet.add(appInfo.getPid());
        }
        execTopCommand();
    }


    public void execTopCommand() {
        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        DataOutputStream os = null;

        try {
            process = Runtime.getRuntime().exec("sh");
            os = new DataOutputStream(process.getOutputStream());
            // donnot use os.writeBytes(commmand), avoid chinese charset
            // error
            os.write(COMMAND_DUMPSYS.getBytes());
            os.writeBytes(COMMAND_LINE_END);
            os.flush();

            os.writeBytes(COMMAND_EXIT);
            os.flush();
            process.waitFor();
            //Log.i(TAG, "successResult reader getEncoding:" + reader.getEncoding());
            successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
            errorResult = new BufferedReader(new InputStreamReader(
                    process.getErrorStream()));
            String stringLine;
            while ((stringLine = successResult.readLine()) != null) {
//                Log.i(TAG, "stringLine:" + stringLine);
                CpuDataUnit cpuDataUnit = isCpuLine(stringLine);
                if (cpuDataUnit != null) {
//                    Log.i(TAG, "successResult readLine, contain true");
                    updateUsage(cpuDataUnit.pid, cpuDataUnit.cpuUsage);
                } else {
//                    Log.i(TAG, "successResult readLine, contain false");
                }
            }
            String stringLineError;
            while ((stringLineError = errorResult.readLine()) != null) {
                Log.i(TAG, "stringLineError:" + stringLineError);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (successResult != null) {
                    successResult.close();
                }
                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (process != null) {
                process.destroy();
            }
        }
    }

    private String parseCpuUsage(String line) {
        Log.i(TAG, "parseCpuUsage, line = " + line);
        String[] splitArray = line.split(" ");
        for (int i = 0; i < splitArray.length; i++) {
            String splitOne = splitArray[i];
            Log.i(TAG, "parseCpuUsage, item[" + i + "] = " + splitOne);
        }
        if (splitArray.length < 22) return "-1.0";
        return splitArray[21];
    }

    private class CpuDataUnit {
        int pid;
        String cpuUsage;

        public CpuDataUnit(int pid, String cpuUsage) {
            this.pid = pid;
            this.cpuUsage = cpuUsage;
        }

        @Override
        public String toString() {
            return "CpuDataUnit: " +
                    "pid=" + pid +
                    ", cpuUsage=" + cpuUsage
                    +".";
        }
    }

    private CpuDataUnit isCpuLine(String line) {
        if (line.startsWith("CPU usage from")
                || line.startsWith("Load")
                || line.contains("TOTAL")) {
            return null;
        }
        String head = line.substring(2, line.indexOf("/"));
//        StringBuilder sb = new StringBuilder();
//        sb.append("head:" + head + ", split:");
        String[] split = head.split(" ");
//        for (String s1 : split) {
//            sb.append(s1 + " ");
//        }
//        Log.i(TAG, "isCpuLine, " + sb);
        CpuDataUnit unit = new CpuDataUnit(Integer.parseInt(split[1]), split[0]);
//        Log.i(TAG, "isCpuLine unit:" + unit);
        if (mPidSet.contains(unit.pid)) {
            return unit;
        }
        return null;
    }

    private void updateUsage(int pid, String usage) {
        for (AppInfo appInfo : runningApps) {
            if (pid == appInfo.getPid()) {
                appInfo.setDumpsysCpuUsage(usage);
                break;
            }
        }
    }
}
